﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Text.RegularExpressions;
using Awesomium.Core;
using System.Diagnostics;
namespace Diplomova_prace
{
    public partial class Nelinear_solutions_win : Form
    {
        Nelinear_Solutions_alg nelinear = new Nelinear_Solutions_alg();
        Reg reg = new Reg();
        Expression expression = new Expression();
        Nelin_ret ret = new Nelin_ret();
        Methods method;
        string NameMethod;
        StringBuilder sb1 = new StringBuilder();
        string pathToHtml = string.Empty;
        readonly string temp = string.Empty;
        StreamWriter sw;
        static int instanceCounter;
        readonly int instanceId;
        string result = string.Empty;
        string formula = string.Empty;
        int defaultFontSize = 24;
        Exports export = new Exports();
        List<Control> alignedComponents = new List<Control>();
        bool incorrect = false;
        public delegate void ParameterizedThreadStart(object obj);
        SaveDialogs save = new SaveDialogs();
        string PathToLastExportFile = string.Empty;

        public enum Methods
        {
            BisectionMethod = 0,
            RegulaFalsiMethod = 1,
            SecantMethod = 2,
            NewtonsMethod = 3,
            SteffensensMethod = 4,
            HalleysMethod = 5
        }
        
        public Nelinear_solutions_win(Methods method, string funkce = "",string dolniMez = "", string horniMez = "", string pocatecniHodnota = "", string presnost = "" , string pocetIteraci = "", string derivace = "", string druhaDerivace = "")
        {
            this.method = method;
            this.instanceId = instanceCounter++;
            InitializeComponent();
            NameWindow();
            DisableComponents();
            AlignComponents();
            FontSize_trackBar.Value = defaultFontSize;
            
            this.Show();
            webControl1.Enabled = true;
            nelinear.error += nelinear_error;
            nelinear.nullDenomi += nelinear_nullDenomi;
            nelinear.nullValue += nelinear_nullValue;
            nelinear.post += nelinear_post;
            expression.incorrectInput += expression_incorrectInput;
            backgroundWorker1.DoWork += new DoWorkEventHandler(DoWork);
            backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Done);
            temp = MainMenu.tempProperty + "NelinearEquation";
            this.FillListChangeMethod(ChangeMethod_ListBox,MainMenu.dictNelTagName);
            funkce_TextBox.Text = funkce;
            dolniMez_TextBox.Text = dolniMez;
            HorniMez_TextBox.Text = horniMez;
            PocatecniHodnota_textBox.Text = pocatecniHodnota;
            presnost_TextBox.Text = presnost;
            PocetIteraci_textBox.Text = pocetIteraci;
            derivace_textBox.Text = derivace;
            druhaDerivace_textBox.Text = druhaDerivace;
        }

        void nelinear_post()
        {
            if (!incorrect)
            {
                MessageBox.Show("Nekorektní vstup", "chyba", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                sw.Close();
                if (backgroundWorker1.IsBusy)
                    backgroundWorker1.CancelAsync();
            }
        }

        void expression_incorrectInput()
        {
            if (!incorrect)
            {
                MessageBox.Show("Nekorektní vstup", "chyba", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                sw.Close();
                incorrect = true;
                VypocitejButton.Enabled = true;
            }
        }

        void nelinear_nullValue()
        {
            MessageBox.Show("Vyskytla se nedefinovaná hodnota", "chyba", MessageBoxButtons.OK, MessageBoxIcon.Stop);
        }
        
        void nelinear_nullDenomi()
        {
            MessageBox.Show("Jmenovatel má nulovou hodnotu", "chyba", MessageBoxButtons.OK, MessageBoxIcon.Stop);
        }

        void nelinear_error()
        {
            MessageBox.Show("Porušeno Bolzanovo kritérium", "chyba", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            sw.Close();
            backgroundWorker1.CancelAsync();
           
        }

        private void VypocitejButton_Click(object sender, EventArgs e)
        {
            RemoveHtmlInstance();
            VypocitejButton.Enabled = false;
            FontSize_trackBar.Value = defaultFontSize;
            DecimalPlaces_numericUpDown.Enabled = false;
            exportyToolStripMenuItem.Enabled = false;
            incorrect = false;
            TimeSpan ts = new TimeSpan(DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second);
            pathToHtml = temp + instanceId + method.ToString() + ts.TotalSeconds.ToString() + ".html";
            toolStripStatusLabel1.Text = string.Empty;
            toolStripSplitButton1.Visible = false;
            this.sw = new StreamWriter(pathToHtml);
            VypocitejButton.Enabled = false;
            if (CheckInput(true))
                sw.Close();
        }
     
        private void DoWork(object sender, DoWorkEventArgs e)
        {
            int countIter = (int) expression.ComputeRPN(expression.RPN(PocetIteraci_textBox.Text));
            double presnost = expression.ComputeRPN(expression.RPN(presnost_TextBox.Text));
            double dolniMez =double.MaxValue;
            double horniMez = double.MinValue;
            double pocatek = double.NaN;
            string firstDerivation = string.Empty;
            string secondDerivation = string.Empty;
            
            if (dolniMez_TextBox.Text != string.Empty)
                dolniMez = expression.ComputeRPN(expression.RPN(dolniMez_TextBox.Text));
            if (HorniMez_TextBox.Text != string.Empty)
                horniMez = expression.ComputeRPN(expression.RPN(HorniMez_TextBox.Text));
            if (PocatecniHodnota_textBox.Text != string.Empty)
                pocatek = expression.ComputeRPN(expression.RPN(PocatecniHodnota_textBox.Text));
            if (derivace_textBox.Text != string.Empty)
                firstDerivation = derivace_textBox.Text;
            if (druhaDerivace_textBox.Text != string.Empty)
                secondDerivation = druhaDerivace_textBox.Text;
            if (method == Methods.BisectionMethod)
            {
                ret = nelinear.BisectionMethod(funkce_TextBox.Text, dolniMez, horniMez, countIter, presnost);
                result = ShowBisectionMethod(ret);
            }
            else if (method == Methods.SecantMethod)
            {
                ret = nelinear.SecantMethod(funkce_TextBox.Text, dolniMez, horniMez, countIter, presnost);
                result = ShowSecantMethod(ret);
            }
            else if (method == Methods.RegulaFalsiMethod)
            {
                ret = nelinear.RegulaFalsi(funkce_TextBox.Text, dolniMez, horniMez, countIter, presnost);
                result = ShowRegulaFalsi(ret);
            }
            else if (method == Methods.NewtonsMethod)
            {
                ret = nelinear.Newton(funkce_TextBox.Text,pocatek,countIter,presnost,firstDerivation);
                result = ShowNewtonsMethod(ret);
            }
            else if (method == Methods.SteffensensMethod)
            {
                ret = nelinear.SteffensenovaMetoda(funkce_TextBox.Text, pocatek, countIter, presnost);
                result = ShowSteffensensMethod(ret);
            }
            else if (method == Methods.HalleysMethod)
            {
                ret = nelinear.HalleyMethod(funkce_TextBox.Text, pocatek, countIter, presnost, firstDerivation, secondDerivation);
                result = ShowHalleysMethod(ret);
            }
            sw.WriteLine(GenerateHtml(result));
            sw.Close();
        }

        private void Done(object sender, RunWorkerCompletedEventArgs e)
        {
            DecimalPlaces_numericUpDown.Enabled = true;
            VypocitejButton.Enabled = true;
            if (!incorrect)
                webControl1.Source = new Uri(Path.GetFullPath(pathToHtml));
         
        }

        private void CheckFillTextBoxs()
        {
            if (funkce_TextBox.Text != string.Empty && PocetIteraci_textBox.Text != string.Empty && presnost_TextBox.Text != string.Empty)
            {
                if ((int)method < 3)
                {
                    if (dolniMez_TextBox.Text != string.Empty && HorniMez_TextBox.Text != string.Empty)
                    {
                        AddTask_Button.Enabled = true;
                        VypocitejButton.Enabled = true;
                    }
                    else
                    {
                        AddTask_Button.Enabled = false;
                        VypocitejButton.Enabled = false;
                    }
                }
                else
                {
                    if (PocatecniHodnota_textBox.Text != string.Empty)
                    {
                        AddTask_Button.Enabled = true;
                        VypocitejButton.Enabled = true;
                    }
                    else
                    {
                        AddTask_Button.Enabled = false;
                        VypocitejButton.Enabled = false;
                    }
                }
            }
            else
            {
                AddTask_Button.Enabled = false;
                VypocitejButton.Enabled = false;
            }
        }

        private bool CheckInput(bool RunWorker)
        {
            this.RemoveSpacesFromTextBoxs();
            string checkInfinity = this.CheckTextBoxsInfinity(expression);
            if (checkInfinity != string.Empty)
            {
                MessageBox.Show("Ve vstupních datech je nastavena nedefinovaná hodnota (" + (checkInfinity) + ")", "Nedefinovaná hodnota", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                VypocitejButton.Enabled = true;
                DecimalPlaces_numericUpDown.Enabled = true;
                return true;
            }
            if (!reg.Check(funkce_TextBox.Text))
            {
                MessageBox.Show("Špatně zadaná funkce", "Funkce", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                
                VypocitejButton.Enabled = true;
                DecimalPlaces_numericUpDown.Enabled = true;
                return true;;
            }
            if (!reg.Check(PocatecniHodnota_textBox.Text))
            {
                MessageBox.Show("Špatně zadaná počáteční hodnota", "Počáteční hodnota", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                
                VypocitejButton.Enabled = true;
                DecimalPlaces_numericUpDown.Enabled = true;
                return true;;
            }
            if (!reg.Check(PocetIteraci_textBox.Text))
            {
                MessageBox.Show("Špatně zadaný počet iterací", "Počet iterací", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                
                VypocitejButton.Enabled = true;
                DecimalPlaces_numericUpDown.Enabled = true;
                return true;;
            }
            if (!reg.Check(presnost_TextBox.Text))
            {
                MessageBox.Show("Špatně zadaná přesnost", "Přesnost", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                
                VypocitejButton.Enabled = true;
                DecimalPlaces_numericUpDown.Enabled = true;
                return true;;
            }
            if (!reg.Check(dolniMez_TextBox.Text))
            {
                MessageBox.Show("Špatně zadaná dolní mez", "Dolní mez", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                
                VypocitejButton.Enabled = true;
                DecimalPlaces_numericUpDown.Enabled = true;
                return true;;
            }
            if (!reg.Check(HorniMez_TextBox.Text))
            {
                MessageBox.Show("Špatně zadaná horní mez", "Horní mez", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                
                VypocitejButton.Enabled = true;
                DecimalPlaces_numericUpDown.Enabled = true;
                return true;;
            }
            if (!reg.Check(derivace_textBox.Text))
            {
                MessageBox.Show("Špatně zadaná derivace", "Derivace", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                
                VypocitejButton.Enabled = true;
                DecimalPlaces_numericUpDown.Enabled = true;
                return true;;
            }
            if (!reg.Check(druhaDerivace_textBox.Text))
            {
                MessageBox.Show("Špatně zadaná druhá derivace", "Druhá derivace", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                
                VypocitejButton.Enabled = true;
                DecimalPlaces_numericUpDown.Enabled = true;
                return true;;
            }
            if (!funkce_TextBox.Text.Contains('x'))
            {
                MessageBox.Show("Musí být zadána funkce", "Funkce", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                
                VypocitejButton.Enabled = true;
                DecimalPlaces_numericUpDown.Enabled = true;
                return true;;
            }
            if (PocatecniHodnota_textBox.Text.Contains('x'))
            {
                MessageBox.Show("Musí být zadána číselná hodnota", "Počáteční hodnota", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                
                VypocitejButton.Enabled = true;
                DecimalPlaces_numericUpDown.Enabled = true;
                return true;;
            }
            if (PocetIteraci_textBox.Text.Contains('x'))
            {
                MessageBox.Show("Musí být zadána číselná hodnota", "Počet iterací", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                DecimalPlaces_numericUpDown.Enabled = true;
                VypocitejButton.Enabled = true;
                
                return true;;
            }
            if (presnost_TextBox.Text.Contains('x'))
            {
                MessageBox.Show("Musí být zadána číselná hodnota", "Přesnost", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                
                VypocitejButton.Enabled = true;
                DecimalPlaces_numericUpDown.Enabled = true;
                return true;;
            }
            if (dolniMez_TextBox.Text.Contains('x'))
            {
                MessageBox.Show("Musí být zadána číselná hodnota", "Dolní mez", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                
                VypocitejButton.Enabled = true;
                DecimalPlaces_numericUpDown.Enabled = true;
                return true;;
            }
            if (HorniMez_TextBox.Text.Contains('x'))
            {
                MessageBox.Show("Musí být zadána číselná hodnota", "Horní mez", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                
                VypocitejButton.Enabled = true;
                DecimalPlaces_numericUpDown.Enabled = true;
                return true;;
            }
            if (expression.ComputeRPN(expression.RPN(presnost_TextBox.Text)) <= 0)
            {
                MessageBox.Show("Přesnost musí být kladná hodnota", "Přesnost", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                
                VypocitejButton.Enabled = true;
                DecimalPlaces_numericUpDown.Enabled = true;
                return true;;
            }
            if (expression.ComputeRPN(expression.RPN(PocetIteraci_textBox.Text)) <= 0 || (Math.Floor(expression.ComputeRPN(expression.RPN(PocetIteraci_textBox.Text))) != expression.ComputeRPN(expression.RPN(PocetIteraci_textBox.Text))))
            {
                MessageBox.Show("Počet iterací musí být kladné přirozené číslo", "Počet iterací", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                
                VypocitejButton.Enabled = true;
                DecimalPlaces_numericUpDown.Enabled = true;
                return true;;
            }
            if ((int)method < 3)
            {
                if (expression.ComputeRPN(expression.RPN(HorniMez_TextBox.Text)) <= expression.ComputeRPN(expression.RPN(dolniMez_TextBox.Text)))
                {
                    MessageBox.Show("Horní mez musí být větší než dolní mez", "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    
                    VypocitejButton.Enabled = true;
                    DecimalPlaces_numericUpDown.Enabled = true;
                    return true;;
                }
            }
            if (!incorrect && RunWorker)
                backgroundWorker1.RunWorkerAsync();
            return false;
        }

        private void AlignComponents()
        {
            int centerPanel = splitContainer1.Panel1.Width / 2;
            if ((int)method < 3)
            {
                VypocitejButton.Location = new Point(centerPanel - VypocitejButton.Size.Width / 2, PocatecniHodnota_textBox.Location.Y);
                PocetIteraci_label.Location = Derivace_label.Location;
                PocetIteraci_textBox.Location = derivace_textBox.Location;
                presnost_label.Location = DruhaDerivace_label.Location;
                presnost_TextBox.Location = druhaDerivace_textBox.Location;
                alignedComponents.Add(PocetIteraci_textBox);
                alignedComponents.Add(presnost_TextBox);
                TabIndexs(3);
            }
            else if (method == Methods.NewtonsMethod)
            {
                VypocitejButton.Location = new Point(centerPanel - VypocitejButton.Size.Width / 2, PocatecniHodnota_textBox.Location.Y);
                presnost_label.Location = DruhaDerivace_label.Location;
                presnost_TextBox.Location = druhaDerivace_textBox.Location;
                presnost_TextBox.TabIndex = druhaDerivace_textBox.TabIndex;

                PocetIteraci_label.Location = Derivace_label.Location;
                PocetIteraci_textBox.Location = derivace_textBox.Location;
                PocetIteraci_textBox.TabIndex = derivace_textBox.TabIndex;

                Derivace_label.Location = dolniMez_label.Location;
                derivace_textBox.Location = dolniMez_TextBox.Location;
                derivace_textBox.TabIndex = dolniMez_TextBox.TabIndex;

                PocatecniHodnota_label.Location = HorniMez_label.Location;
                PocatecniHodnota_textBox.Location = HorniMez_TextBox.Location;
                PocatecniHodnota_textBox.TabIndex = HorniMez_TextBox.TabIndex;
             
                alignedComponents.Add(derivace_textBox);
                alignedComponents.Add(PocatecniHodnota_textBox);
                alignedComponents.Add(PocetIteraci_textBox);
                alignedComponents.Add(presnost_TextBox);
                TabIndexs(1);
            }
            else if (method == Methods.SteffensensMethod)
            {
                VypocitejButton.Location = new Point(centerPanel - VypocitejButton.Size.Width / 2, druhaDerivace_textBox.Location.Y);
                PocatecniHodnota_label.Location = dolniMez_label.Location;
                PocatecniHodnota_textBox.Location = dolniMez_TextBox.Location;
                PocetIteraci_label.Location = HorniMez_label.Location;
                PocetIteraci_textBox.Location = HorniMez_TextBox.Location;
                presnost_label.Location = Derivace_label.Location;
                presnost_TextBox.Location = derivace_textBox.Location;
                alignedComponents.Add(PocatecniHodnota_textBox);
                alignedComponents.Add(PocetIteraci_textBox);
                alignedComponents.Add(presnost_TextBox);
                TabIndexs(1);
            }
            
            else if (method == Methods.HalleysMethod)
            {
                VypocitejButton.Location = new Point(centerPanel - VypocitejButton.Size.Width / 2, PocetIteraci_textBox.Location.Y);
                presnost_label.Location = PocatecniHodnota_label.Location;
                presnost_TextBox.Location = PocatecniHodnota_textBox.Location;

                PocatecniHodnota_label.Location = Derivace_label.Location;
                PocatecniHodnota_textBox.Location = derivace_textBox.Location;

                PocetIteraci_label.Location = DruhaDerivace_label.Location;
                PocetIteraci_textBox.Location = druhaDerivace_textBox.Location;

                Derivace_label.Location = dolniMez_label.Location;
                derivace_textBox.Location = dolniMez_TextBox.Location;

                DruhaDerivace_label.Location = HorniMez_label.Location;
                druhaDerivace_textBox.Location = HorniMez_TextBox.Location;
               

                alignedComponents.Add(derivace_textBox);
                alignedComponents.Add(druhaDerivace_textBox);
                alignedComponents.Add(PocatecniHodnota_textBox);
                alignedComponents.Add(PocetIteraci_textBox);
                alignedComponents.Add(presnost_TextBox);
                TabIndexs(1);
            }
            
        }

        private void TabIndexs(int firstIndex)
        {
            for (int i = 0; i < alignedComponents.Count; i++)
                alignedComponents[i].TabIndex = firstIndex+i;
        }

        private void DisableComponents()
        {
            if ((int)method < 3)
            {
                PocatecniHodnota_textBox.Visible = false;
                PocatecniHodnota_label.Visible = false;
                derivace_textBox.Visible = false;
                Derivace_label.Visible = false;
                druhaDerivace_textBox.Visible = false;
                DruhaDerivace_label.Visible = false;
            }
            else if (method == Methods.NewtonsMethod)
            {
                HorniMez_label.Visible = false;
                HorniMez_TextBox.Visible = false;
                dolniMez_label.Visible = false;
                dolniMez_TextBox.Visible = false;
                DruhaDerivace_label.Visible = false;
                druhaDerivace_textBox.Visible = false;
            }
            else if (method == Methods.SteffensensMethod)
            {
                derivace_textBox.Visible = false;
                Derivace_label.Visible = false;
                druhaDerivace_textBox.Visible = false;
                DruhaDerivace_label.Visible = false;
                HorniMez_label.Visible = false;
                HorniMez_TextBox.Visible = false;
                dolniMez_label.Visible = false;
                dolniMez_TextBox.Visible = false;
            }
            else if (method == Methods.HalleysMethod)
            {
                HorniMez_label.Visible = false;
                HorniMez_TextBox.Visible = false;
                dolniMez_label.Visible = false;
                dolniMez_TextBox.Visible = false;
            }
        }

        private void NameWindow()
        {
            if (method == Methods.BisectionMethod)
            {
                this.Text = "Metoda půlení intervalu";
                formula = Formulas.BisectionMethod;
            }
            else if (method == Methods.SecantMethod)
            {
                this.Text = "Metoda sečen";
                formula = Formulas.SecantMethod;
            }
            else if (method == Methods.RegulaFalsiMethod)
            {
                this.Text = "Metoda Regula Falsi";
                formula = Formulas.RegulaFalsi;
            }
            else if (method == Methods.NewtonsMethod)
            {
                this.Text = "Newtonova metoda";
                formula = Formulas.NewtonsMethod;
            }
            else if (method == Methods.SteffensensMethod)
            {
                this.Text = "Steffensenova metoda";
                formula = Formulas.SteffensensMethod;
            }
            else if (method == Methods.HalleysMethod)
            {
                this.Text = "Halleyova metoda";
                formula = Formulas.HalleysMethod;
            }
            NameMethod = this.Text;
        }

        private void RemoveHtmlInstance()
        {
            string directory = Directory.GetCurrentDirectory();
            List<string> files = Directory.GetFiles(directory).ToList();
            foreach (string file in files)
            {
                if (file.Contains(temp + instanceId + method.ToString()))
                {
                    File.Delete(Path.GetFullPath(file));
                }
            }
        }

        private string ShowNewtonsMethod(Nelin_ret vstup)
        {
            StringBuilder sb = new StringBuilder();
            List<string> vyraz = new List<string>();
            for (int i = 0; i < vstup.derfxProperty.Count; i++)
            {
                if (i == 0)
                    vyraz.Add(string.Empty);
                vyraz.Add(vstup.xProperty[i].NumToMathml() + Mathml.Minus + Mathml.Frac(vstup.fxProperty[i].NumToMathml(), vstup.derfxProperty[i].NumToMathml()));
            }
            int SizeTable = 15;
            int countIter = (int)Math.Ceiling((double)vstup.xProperty.Count / SizeTable);

            for (int i = 0; i < countIter; i++)
            {
                int start = 0 + i * SizeTable;
                int end;
                if (i + 1 != countIter)
                    end = SizeTable;
                else
                    if (vstup.xProperty.Count % SizeTable != 0)
                        end = vstup.xProperty.Count % SizeTable;
                    else
                        end = SizeTable;
                sb.Append(Mathml.HeaderMath());
                if (i == 0)
                    sb.Append(Mathml.TableNelinear(vstup.xProperty.GetRange(start, end), vstup.fxProperty.GetRange(start, end), vyraz.GetRange(start, end), true, i * SizeTable));
                else
                    sb.Append(Mathml.TableNelinear(vstup.xProperty.GetRange(start, end), vstup.fxProperty.GetRange(start, end), vyraz.GetRange(start, end), false, i * SizeTable));
                sb.Append(Mathml.EndMath);
            }
            return sb.ToString();
        }

        private string ShowSteffensensMethod(Nelin_ret vstup)
        {
            StringBuilder sb = new StringBuilder();
            List<string> vyraz = new List<string>();
            for (int i = 0; i < vstup.derfxProperty.Count; i++)
            {
                if (i == 0)
                    vyraz.Add(Mathml.Frac(string.Empty, string.Empty)); //kvůli stejné výšce řádku ve výpisu
                vyraz.Add(vstup.xProperty[i].NumToMathml() + Mathml.Minus + Mathml.Frac(Mathml.Sup(Mathml.LZ + vstup.fxProperty[i].NumToMathml() + Mathml.PZ, Mathml.Constant(2)), vstup.derfxProperty[i].NumToMathml() + (-1 * vstup.fxProperty[i]).NumToMathml("+", "+")));
            }
            int SizeTable = 10;
            int countIter = (int)Math.Ceiling((double)vstup.xProperty.Count / SizeTable);

            for (int i = 0; i < countIter; i++)
            {
                int start = 0 + i * SizeTable;
                int end;
                if (i + 1 != countIter)
                    end = 10;
                else
                    if (vstup.xProperty.Count % SizeTable != 0)
                        end = vstup.xProperty.Count % SizeTable;
                    else
                        end = SizeTable;
                sb.Append(Mathml.HeaderMath());
                if (i == 0)
                    sb.Append(Mathml.TableNelinear(vstup.xProperty.GetRange(start, end), vstup.fxProperty.GetRange(start, end), vyraz.GetRange(start, end), true, i * SizeTable));
                else
                    sb.Append(Mathml.TableNelinear(vstup.xProperty.GetRange(start, end), vstup.fxProperty.GetRange(start, end), vyraz.GetRange(start, end), false, i * SizeTable));
                sb.Append(Mathml.EndMath);
            }
            return sb.ToString();
        }

        private string ShowHalleysMethod(Nelin_ret vstup)
        {
            StringBuilder sb = new StringBuilder();
            List<string> vyraz = new List<string>();
            for (int i = 0; i < vstup.derfxProperty.Count; i++)
            {
                if (i == 0)
                    vyraz.Add(string.Empty);
                vyraz.Add(vstup.xProperty[i].NumToMathml() + Mathml.Minus + Mathml.Frac(Mathml.Constant(2) + Mathml.Multiply + vstup.fxProperty[i].Bracket() + Mathml.Multiply + vstup.derfxProperty[i].Bracket(), Mathml.Constant(2) + Mathml.Multiply + Mathml.Sup(vstup.derfxProperty[i].Bracket(), Mathml.Constant(2)) + (-1 * vstup.fxProperty[i]).NumToMathml("+", "+") + Mathml.Multiply + vstup.secondDerFxProperty[i].Bracket()));
            }
            int SizeTable = 10;
            int countIter = (int)Math.Ceiling((double)vstup.xProperty.Count / SizeTable);

            for (int i = 0; i < countIter; i++)
            {
                int start = 0 + i * SizeTable;
                int end;
                if (i + 1 != countIter)
                    end = 10;
                else
                    if (vstup.xProperty.Count % SizeTable != 0)
                        end = vstup.xProperty.Count % SizeTable;
                    else
                        end = SizeTable;
                sb.Append(Mathml.HeaderMath());
                if (i == 0)
                    sb.Append(Mathml.TableNelinear(vstup.xProperty.GetRange(start, end), vstup.fxProperty.GetRange(start, end), vyraz.GetRange(start, end), true, i * SizeTable));
                else
                    sb.Append(Mathml.TableNelinear(vstup.xProperty.GetRange(start, end), vstup.fxProperty.GetRange(start, end), vyraz.GetRange(start, end), false, i * SizeTable));
                sb.Append(Mathml.EndMath);
            }
            return sb.ToString();
        }

        private string ShowSecantMethod(Nelin_ret vstup)
        {
            StringBuilder sb = new StringBuilder();
            List<string> vyraz = new List<string>();
            if (vstup.xProperty.Count > 2)
            {
                for (int i = 1; i < vstup.xProperty.Count - 1; i++)
                {
                    vyraz.Add(vstup.xProperty[i].NumToMathml() + Mathml.Minus + Mathml.Frac(Mathml.LZ + vstup.xProperty[i].NumToMathml() + (-1 * vstup.xProperty[i - 1]).NumToMathml("+", "+") + Mathml.PZ + Mathml.Multiply + vstup.fxProperty[i].Bracket(), vstup.fxProperty[i].NumToMathml() + (-1 * vstup.fxProperty[i - 1]).NumToMathml("+", "+")));
                }
                for (int i = 0; i < 2; i++)
                {
                    vstup.xProperty.RemoveAt(0);
                    vstup.fxProperty.RemoveAt(0);
                }
                int SizeTable = 10;
                int countIter = (int)Math.Ceiling((double)vstup.xProperty.Count / SizeTable);

                for (int i = 0; i < countIter; i++)
                {
                    int start = 0 + i * SizeTable;
                    int end;
                    if (i + 1 != countIter)
                        end = SizeTable;
                    else
                        if (vstup.xProperty.Count % SizeTable != 0)
                            end = vstup.xProperty.Count % SizeTable;
                        else
                            end = SizeTable;
                    sb.Append(Mathml.HeaderMath());
                    if (i == 0)
                        sb.Append(Mathml.TableNelinear(vstup.xProperty.GetRange(start, end), vstup.fxProperty.GetRange(start, end), vyraz.GetRange(start, end), true, i * SizeTable));
                    else
                        sb.Append(Mathml.TableNelinear(vstup.xProperty.GetRange(start, end), vstup.fxProperty.GetRange(start, end), vyraz.GetRange(start, end), false, i * SizeTable));
                    sb.Append(Mathml.EndMath);
                }
            }
            else
            {
                sb.Append(Mathml.HeaderMath());
                if (vstup.fxProperty[0] == 0)
                    sb.Append(Mathml.TableNelinear(vstup.xProperty.GetRange(0, 1), vstup.fxProperty.GetRange(0, 1), new List<string>() { string.Empty }, true, 0));
                else
                    sb.Append(Mathml.TableNelinear(vstup.xProperty.GetRange(1, 1), vstup.fxProperty.GetRange(1, 1), new List<string>() { string.Empty }, true, 0));

            }
            return sb.ToString();
        }

        private string ShowBisectionMethod(Nelin_ret vstup)
        {
            StringBuilder sb = new StringBuilder();
            List<string> vyraz = new List<string>();
            int a = 0;
            int b = 1;
            if (vstup.xProperty.Count > 2)
            {
                vyraz.Add(Mathml.Frac(vstup.xProperty[a].NumToMathml() + vstup.xProperty[b].NumToMathml("+", "+"), Mathml.Constant(2)));
                for (int i = 2; i < vstup.xProperty.Count; i++)
                {
                    if (vstup.fxProperty[i] * vstup.fxProperty[a] > 0)
                    {
                        a = i;
                    }
                    else if (vstup.fxProperty[i] * vstup.fxProperty[a] <= 0)
                    {
                        b = i;
                    }
                    vyraz.Add(Mathml.Frac(vstup.xProperty[a].NumToMathml() + vstup.xProperty[b].NumToMathml("+", "+"), Mathml.Constant(2)));
                }
                for (int i = 0; i < 2; i++)
                {
                    vstup.xProperty.RemoveAt(0);
                    vstup.fxProperty.RemoveAt(0);
                }

                int SizeTable = 10;
                int countIter = (int)Math.Ceiling((double)vstup.xProperty.Count / SizeTable);

                for (int i = 0; i < countIter; i++)
                {
                    int start = 0 + i * SizeTable;
                    int end;
                    if (i + 1 != countIter)
                        end = SizeTable;
                    else
                        if (vstup.xProperty.Count % SizeTable != 0)
                            end = vstup.xProperty.Count % SizeTable;
                        else
                            end = SizeTable;
                    sb.Append(Mathml.HeaderMath());
                    if (i == 0)
                        sb.Append(Mathml.TableNelinear(vstup.xProperty.GetRange(start, end), vstup.fxProperty.GetRange(start, end), vyraz.GetRange(start, end), true, i * SizeTable));
                    else
                        sb.Append(Mathml.TableNelinear(vstup.xProperty.GetRange(start, end), vstup.fxProperty.GetRange(start, end), vyraz.GetRange(start, end), false, i * SizeTable));
                    sb.Append(Mathml.EndMath);
                }
            }
            else
            {
                sb.Append(Mathml.HeaderMath());
                if (vstup.fxProperty[0] == 0)
                    sb.Append(Mathml.TableNelinear(vstup.xProperty.GetRange(0, 1), vstup.fxProperty.GetRange(0, 1), new List<string>() { string.Empty}, true, 0));
                else
                    sb.Append(Mathml.TableNelinear(vstup.xProperty.GetRange(1, 1), vstup.fxProperty.GetRange(1, 1), new List<string>() { string.Empty }, true, 0));

            }

            return sb.ToString();
        }

        private string ShowRegulaFalsi(Nelin_ret vstup)
        {
            StringBuilder sb = new StringBuilder();
            List<string> vyraz = new List<string>();
            int a = 0;
            int b = 1;
            if (vstup.xProperty.Count > 2)
            {
                vyraz.Add(Mathml.Frac(vstup.fxProperty[b].NumToMathml() + Mathml.Multiply + vstup.xProperty[a].Bracket() + (-1 * vstup.fxProperty[a]).NumToMathml("+", "+") + Mathml.Multiply + vstup.xProperty[b].Bracket(), vstup.fxProperty[b].NumToMathml() + (-1 * vstup.fxProperty[a]).NumToMathml("+", "+")));
                for (int i = 2; i < vstup.xProperty.Count; i++)
                {
                    if (vstup.fxProperty[i] * vstup.fxProperty[a] > 0)
                    {
                        a = i;
                    }
                    else if (vstup.fxProperty[i] * vstup.fxProperty[a] < 0)
                    {
                        b = i;
                    }
                    vyraz.Add(Mathml.Frac(vstup.fxProperty[b].NumToMathml() + Mathml.Multiply + vstup.xProperty[a].Bracket() + (-1 * vstup.fxProperty[a]).NumToMathml("+", "+") + Mathml.Multiply + vstup.xProperty[b].Bracket(), vstup.fxProperty[b].NumToMathml() + (-1 * vstup.fxProperty[a]).NumToMathml("+", "+")));
                }
                for (int i = 0; i < 2; i++)
                {
                    vstup.xProperty.RemoveAt(0);
                    vstup.fxProperty.RemoveAt(0);
                }
                int SizeTable = 10;
                int countIter = (int)Math.Ceiling((double)vstup.xProperty.Count / SizeTable);

                for (int i = 0; i < countIter; i++)
                {
                    int start = 0 + i * SizeTable;
                    int end;
                    if (i + 1 != countIter)
                        end = SizeTable;
                    else
                        if (vstup.xProperty.Count % SizeTable != 0)
                            end = vstup.xProperty.Count % SizeTable;
                        else
                            end = SizeTable;
                    sb.Append(Mathml.HeaderMath());
                    if (i == 0)
                        sb.Append(Mathml.TableNelinear(vstup.xProperty.GetRange(start, end), vstup.fxProperty.GetRange(start, end), vyraz.GetRange(start, end), true, i * SizeTable));
                    else
                        sb.Append(Mathml.TableNelinear(vstup.xProperty.GetRange(start, end), vstup.fxProperty.GetRange(start, end), vyraz.GetRange(start, end), false, i * SizeTable));
                    sb.Append(Mathml.EndMath);
                }
            }
            else
            {
                sb.Append(Mathml.HeaderMath());
                if (vstup.fxProperty[0] == 0)
                    sb.Append(Mathml.TableNelinear(vstup.xProperty.GetRange(0, 1), vstup.fxProperty.GetRange(0, 1), new List<string>() { string.Empty }, true, 0));
                else
                    sb.Append(Mathml.TableNelinear(vstup.xProperty.GetRange(1, 1), vstup.fxProperty.GetRange(1, 1), new List<string>() { string.Empty }, true, 0));

            }
            return sb.ToString();
        }

        private void funkce_TextBox_TextChanged(object sender, EventArgs e)
        {
            CheckFillTextBoxs();
        }

        private void dolniMez_TextBox_TextChanged(object sender, EventArgs e)
        {
            CheckFillTextBoxs();
        }

        private void HorniMez_TextBox_TextChanged(object sender, EventArgs e)
        {
            CheckFillTextBoxs();
        }

        private void PocetDilu_textBox_TextChanged(object sender, EventArgs e)
        {
            CheckFillTextBoxs();
        }

        private void presnost_TextBox_TextChanged(object sender, EventArgs e)
        {
            CheckFillTextBoxs();
        }

        private void pocatecni_hodnota_textBox_TextChanged(object sender, EventArgs e)
        {
            CheckFillTextBoxs();
        }

        private void derivace_textBox_TextChanged(object sender, EventArgs e)
        {
            CheckFillTextBoxs();
        }

        private void druhaDerivace_textBox_TextChanged(object sender, EventArgs e)
        {
            CheckFillTextBoxs();
        }

        private void FontSize_trackBar_MouseUp(object sender, MouseEventArgs e)
        {
            string size = FontSize_trackBar.Value.ToString();
            webControl1.ExecuteJavascript("changeSize('" + size + "px')");
            toolStripStatusLabel1.Text = string.Empty;
        }

        private void FontSize_trackBar_KeyUp(object sender, KeyEventArgs e)
        {
            string size = FontSize_trackBar.Value.ToString();
            webControl1.ExecuteJavascript("changeSize('" + size + "px')");
            toolStripStatusLabel1.Text = string.Empty;
        }

        private void Awesomium_Windows_Forms_WebControl_DocumentReady(object sender, Awesomium.Core.UrlEventArgs e)
        {
            FontSize_trackBar.Enabled = true;
            while (!webControl1.ExecuteJavascriptWithResult("IsCompleted()")) ;
            exportyToolStripMenuItem.Enabled = true;
        }

        private void Nelinear_solutions_win_FormClosing(object sender, FormClosingEventArgs e)
        {
            RemoveHtmlInstance();
        }

        private void xMLToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (save.SaveAsXML(result))
            {
                toolStripStatusLabel1.Text = Path.GetFileName(save.PathToDestinationFileProperty) + " soubor byl vytvořen";
                toolStripSplitButton1.Visible = true;
                PathToLastExportFile = save.PathToDestinationFileProperty;
            }
        }

        private void hTMLToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (save.SaveAsHTML(result))
            {
                toolStripStatusLabel1.Text = Path.GetFileName(save.PathToDestinationFileProperty) + " soubor byl vytvořen";
                toolStripSplitButton1.Visible = true;
                PathToLastExportFile = save.PathToDestinationFileProperty;
            }
        }

        private string GenerateHtml(string input)
        {
            string currDirectory = Directory.GetCurrentDirectory();
            StringBuilder divInput = new StringBuilder(Html.Div() + Html.Span("Byla zadána funkce:    ")+Mathml.HeaderMath(Mathml.Display.inline)+Mathml.Literal("f")+Mathml.LZ+Mathml.Literal("x")+Mathml.PZ + Mathml.Equal + Mathml.Space() + Mathml.EndMath + expression.TextToMathml(funkce_TextBox.Text, Mathml.Display.inline)
                + Html.Span(".") + Html.Br + Html.Span("Úkolem je nalezení kořene zadané rovnice "));
            if ((int)method < 3)
            {
                string dolniMez = (expression.TextToMathml(dolniMez_TextBox.Text, Mathml.Display.inline)).Replace(Mathml.HeaderMath(Mathml.Display.inline), string.Empty);
                dolniMez = dolniMez.Replace(Mathml.EndMath, string.Empty);

                string horniMez = (expression.TextToMathml(HorniMez_TextBox.Text, Mathml.Display.inline)).Replace(Mathml.HeaderMath(Mathml.Display.inline), string.Empty);
                horniMez = horniMez.Replace(Mathml.EndMath, string.Empty);
                divInput.Append(Html.Span(" na intervalu:    ")
                    + Mathml.HeaderMath(Mathml.Display.inline) + Mathml.TypeBracket.hranate.ToDescription() + dolniMez + Mathml.Text(";") + horniMez
                    + Mathml.EndMfenced + Mathml.EndMath);
                divInput.Append(Html.Span(".") + Html.Br);
            }
            else
            {
                divInput.Append(Html.Span(" s počáteční hodnotou:    ") + expression.TextToMathml(PocatecniHodnota_textBox.Text, Mathml.Display.inline));
                divInput.Append(Html.Span(".") + Html.Br);
            }
            divInput.Append(Html.Span(" Zvolená metoda:   ") + Html.Span(NameMethod) + Html.Br);
            divInput.Append(Html.Span("Předpis zvolené metody:") + Html.Br + formula + Html.Br);
            if (derivace_textBox.Text != string.Empty)
                divInput.Append(Html.Span("První derivace byla zadána analyticky:    ") + expression.TextToMathml(derivace_textBox.Text, Mathml.Display.inline) + Html.Br);
            if (druhaDerivace_textBox.Text != string.Empty)
                divInput.Append(Html.Span("Druhá derivace byla zadána analyticky:   ") + expression.TextToMathml(druhaDerivace_textBox.Text, Mathml.Display.inline) + Html.Br);


            divInput.Append(Html.Span("Maximální počet iterací:    ") + expression.TextToMathml(PocetIteraci_textBox.Text, Mathml.Display.inline) + Html.Br);
            divInput.Append(Html.Span("Požadovaná přesnost výsledku:    ") + expression.TextToMathml(presnost_TextBox.Text, Mathml.Display.inline) + Html.Br);

            divInput.Append(Html.Span("Výsledek") + Html.Br + Html.EndDiv);
            input = Html.Div() + input + Html.EndDiv;
            result = Html.HeaderHTML(NameMethod) + divInput.ToString() + input + Html.EndHTML;
            return result;

        }

        private void imageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (result != string.Empty)
            {
                int width = int.Parse(webControl1.ExecuteJavascriptWithResult("WidthDiv()"));
                int height = int.Parse(webControl1.ExecuteJavascriptWithResult("HeightDiv()"));
                int fontSize = FontSize_trackBar.Value;
                if (save.SaveAsImage(result, width, height, fontSize, pathToHtml))
                {
                    toolStripStatusLabel1.Text = Path.GetFileName(save.PathToDestinationFileProperty) + " soubor byl vytvořen";
                    toolStripSplitButton1.Visible = true;
                    PathToLastExportFile = save.PathToDestinationFileProperty;
                }
            }
        }

        private void splitContainer1_SplitterMoved(object sender, SplitterEventArgs e)
        {
            webControl1.Reload(true);
            FontSize_trackBar.Value = defaultFontSize;
        }

        private void pDFToolStripMenuItem_Click(object sender, EventArgs e)
        {
          /*  if (result != string.Empty)
            {
                int width = int.Parse(webControl1.ExecuteJavascriptWithResult("WidthDiv()"));
                int height = int.Parse(webControl1.ExecuteJavascriptWithResult("HeightDiv()"));
                int fontSize = FontSize_trackBar.Value;
                if (save.SaveAsPDF(result, width, height, fontSize))
                {
                    toolStripStatusLabel1.Text = Path.GetFileName(save.PathToDestinationFileProperty) + " soubor byl vytvořen";
                    toolStripSplitButton1.Visible = true;
                    PathToLastExportFile = save.PathToDestinationFileProperty;
                }
            }*/
        }

        private void DecimalPlaces_numericUpDown_ValueChanged(object sender, EventArgs e)
        {
            Extension.countDecimalPlaces = (int)DecimalPlaces_numericUpDown.Value;
        }

        private void ChangeMethod_ListBox_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            Nelinear_solutions_win nelinar;
            if (ChangeMethod_ListBox.SelectedIndex > -1)
                nelinar = new Nelinear_solutions_win((Methods)ChangeMethod_ListBox.SelectedIndex,
                    (funkce_TextBox.Visible) ? funkce_TextBox.Text : string.Empty,
                    (dolniMez_TextBox.Visible) ? dolniMez_TextBox.Text : string.Empty,
                    (HorniMez_TextBox.Visible) ? HorniMez_TextBox.Text : string.Empty,
                    (PocatecniHodnota_textBox.Visible) ? PocatecniHodnota_textBox.Text : string.Empty,
                    (presnost_TextBox.Visible) ? presnost_TextBox.Text : string.Empty,
                    (PocetIteraci_textBox.Visible) ? PocetIteraci_textBox.Text : string.Empty,
                    (derivace_textBox.Visible) ? derivace_textBox.Text : string.Empty,
                    (druhaDerivace_textBox.Visible) ? druhaDerivace_textBox.Text : string.Empty);
        }

        private void AddTask_Button_Click(object sender, EventArgs e)
        {
            if (!CheckInput(false))
                AddTask();
        }

        private void AddTask()
        {
            DateTime date = DateTime.Now;      
            string file = date.ToString("yyyyMMddHHmmss") + ".xml";
            string[] Files = Directory.GetFiles(Directory.GetCurrentDirectory() + MainMenu.PathTaskNelProperty + MainMenu.dictNelTagName[(int)method]);
            string path = Directory.GetCurrentDirectory() + MainMenu.PathTaskNelProperty + MainMenu.dictNelTagName[(int)method] + "\\" + file;
            StreamWriter stw = new StreamWriter(path);
            stw.WriteLine("<?xml version='1.0' encoding='UTF-8'?>");
            stw.WriteLine("<uloha>");
            stw.WriteLine("<funkce>" + funkce_TextBox.Text + "</funkce>");
            if (dolniMez_TextBox.Visible && dolniMez_TextBox.Text != string.Empty)
                stw.WriteLine("<dolni_mez>" + dolniMez_TextBox.Text + "</dolni_mez>");
            if (HorniMez_TextBox.Visible && HorniMez_TextBox.Text != string.Empty)
                stw.WriteLine("<horni_mez>" + HorniMez_TextBox.Text + "</horni_mez>");
            if (PocatecniHodnota_textBox.Visible && PocatecniHodnota_textBox.Text != string.Empty)
                stw.WriteLine("<pocatecni_hodnota>" + PocatecniHodnota_textBox.Text + "</pocatecni_hodnota>");
            stw.WriteLine("<presnost>" + presnost_TextBox.Text + "</presnost>");
            stw.WriteLine("<pocet_iteraci>" + PocetIteraci_textBox.Text + "</pocet_iteraci>");
            if (derivace_textBox.Visible && derivace_textBox.Text != string.Empty)
                stw.WriteLine("<derivace>" + derivace_textBox.Text + "</derivace>");
            if (druhaDerivace_textBox.Visible && druhaDerivace_textBox.Text != string.Empty)
                stw.WriteLine("<druha_derivace" + druhaDerivace_textBox.Text + "</druha_derivace>");
            stw.WriteLine("</uloha>");
            stw.Close();
            StreamReader sr = new StreamReader(Directory.GetCurrentDirectory() + MainMenu.PathTaskNelProperty + MainMenu.dictNelTagName[(int)method] + "\\" + file);
            string tmp = sr.ReadToEnd().Trim();
            foreach (string item in Files)
            {
                StreamReader str = new StreamReader(item);
                string tmp1 = str.ReadToEnd().Trim();
                if (tmp == tmp1)
                {
                    MessageBox.Show("Tato úloha byla již přidána", "Existující úloha", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    str.Close();
                    sr.Close();
                    File.Delete(Directory.GetCurrentDirectory() + MainMenu.PathTaskNelProperty + MainMenu.dictNelTagName[(int)method] + "\\" + file);
                    return;
                }
                str.Close();
            }
            sr.Close();
            toolStripStatusLabel1.Text = "Úloha byla přidána do cvičných úloh";
        }

        private void toolStripSplitButton1_ButtonClick(object sender, EventArgs e)
        {
            Process.Start(PathToLastExportFile);
        }

        private void toolStripSplitButton1_MouseHover(object sender, EventArgs e)
        {
            statusStrip.ShowItemToolTips = true;
            toolStripSplitButton1.ToolTipText = "otevřít soubor";
        }
     

    }
}
